This invention relates generally to computer software diagnostic tools and, more particularly, relates to injecting code into another process.
Many software programs and computer-oriented tools and techniques monitor and analyze executable programs and modules. In many instances, these software programs, tools, and techniques may need to control another program (i.e., xe2x80x9ctarget processxe2x80x9d), change a target process"" behavior with the target process being unaware of the change in control or behavior, or determine how the target process will interact with other programs and the operating system in which the target process will be run.
For example, anti-virus software needs to map into the target process and determine what the target process will do when it is activated. Debuggers are used to detect, locate, and correct logical or syntactical errors in the target process. They allow a programmer to step through a target process, examine the data, and monitor conditions (such as variables) in the target process. Profilers analyze a target process and determine the time that the process spends in various parts the process during execution. This is often used to determine which API (Application Programming Interface) calls are taking up time. Security check tools verify that a user is authorized to execute a particular process or that a target process is allowed to run a particular task. API interception techniques intercept program calls sent to a target process or sent from a target process. This requires mapping into the target process at the beginning of the process"" execution and is done for a variety of reasons including testing the target process, profiling, monitoring selected events, and re-directing the API call to another process. Pseudo-localization attempts to anticipate what a target process will do when that process and the process"" resources are changed into a different language for operation in different regions of the world.
One way of implementing these software programs, tools, and techniques (e.g., anti-virus, debugging, profiling, API interception, security checks, pseudo-localization, etc.) is by mapping, or injecting, a module into the target process in order to execute certain tasks. The term xe2x80x9cmodulexe2x80x9d includes any routine, program, object, component, data structure, etc. that performs particular tasks or implements particular abstract data types. Several methods have been developed to inject a module into another process to assist in the development of the software programs, tools, and techniques. These methods are injecting the module using the operating system""s registry, injecting the module using hooks, injecting the module using remote threads, injecting the module as a debugger, and injecting the module with a Trojan process.
The method of injecting a module via an operating system""s registry is limited only to those operating systems that use a system registry. A system registry contains the configuration for the operating system. This method works by modifying one of the key entries in the register and placing the name of the module and its path in the key entry. When the operating system is restarted, the system saves the value of the key during the initialization process and loads each module in the key when one of the system libraries is mapped into a process. For example, in Microsoft(copyright) Windows NT(copyright), when the User32.dll library is mapped into a process, User32.dll retrieves the saved value of the Applnit_DLLs key and loads each module specified in the string. There are several limitations to this method. The operating system must be restarted for this method to work and it does not work in every operating system that uses a registry. For example, it will not work in Microsoft(copyright) Windows(copyright) 98. Additionally, it only works with those processes that use User32.dll, which are all GUI (Graphical User Interface) based applications. The method will not work on console user interface (CUI) based applications (i.e., text-based). Another limitation is that the injected module will be mapped into every GUI-based application, which is not necessary and increases the likelihood of an operating system crash.
Another method of injecting a module into a target process uses hooks. A hook is a point in an operating system""s message-handling mechanism where an application can monitor messages in the operating system for specified events and process certain types of messages before the messages reach the target process. For example, in Microsoft Windows operating systems, one type of hook monitors messages posted to a queue and calls a predefined code before the message is processed. When the target process prepares to send a message, the operating system checks to see if the module containing the predefined code that the hook calls is mapped into the target process"" address space (i.e., memory area). If the module is not mapped, the operating system forces the module to be mapped into the target process"" address space. The drawback to this method is that it has effect only after the target process has been started. This is a significant limitation for tools like profilers that need to be mapped into the target process virtual address area as soon as the target process starts.
A third method of injecting a module into a target process uses remote threads. This is specific to operating systems that use threads and that allow remote threads to be created. A thread is created in the context of a process and it executes code within its process"" address space and manipulates data within its process"" address space. Two or more threads running in the same process share the process"" address space, can execute the same code and manipulate the same data. A remote thread is created and controlled by a process to run in the address space of a target process. The drawback to this approach is that is does not work in every operating system that uses threads. For example, Microsoft(copyright) Windows(copyright) 2000 supports remote thread creation while Microsoft(copyright) Windows(copyright) 95 and Microsoft(copyright) Windows(copyright) 98 do not support remote thread creation. Additionally, the target process must be running when the remote thread is created.
Injecting a module into a target process can also be done by injecting the module as a debugger. It is well known that when a debuggee process loads, the operating system automatically notifies the debugger when the debuggee process"" address space is ready. This notification occurs prior to the debuggee process executing any code. When the notification arrives, the debugger can force code into the debuggee""s address space and then cause the debuggee process to execute that code. The major drawback to this approach is that the target process runs in the debug mode instead of running as it normally would. This affects the target process"" behavior and significantly affects the target process"" performance. Additionally, many operating systems terminate the debugger if the debuggee process is terminated.
Another method to inject a module into a target process is to inject the module as a Trojan process. This requires knowing what modules the target process will load. One of the modules the target process will load is overwritten or replaced with the injected module. When the target process loads the module, the injected module will be loaded by the target process in place of the original module. This method has the drawback of requiring the target process to be running, which limits is usefulness for tools like profilers that need to be mapped into the target process"" address space as soon as the target process starts.
What is needed is a method to inject a module into a target process that is injected as soon as the target process starts, that works on both console and GUI applications, and that does not require the target process to be run as a debuggee, and that preferably works on different implementations of the Win32(copyright) architecture.
In view of the above-described problems existing in the art, the present invention provides a mechanism for mapping a module into a target process in an operating system. The invention allows the module to be injected into the target process as soon as the target process starts. The module is injected before any target process instructions are executed. The mechanism works on both console and GUI applications and it does not require the target process to be run as a debugee.
In order to provide this mechanism, the system architecture must provide the capability to find the location in memory (i.e., starting address) where the target process will begin execution. The starting address of the target process is retrieved. The target process is then loaded as suspended so that no target process instructions are executed. The target process starting instructions are saved, and thereafter instructions are forced into the starting address. These instructions, when executed, load a helper module that loads the module to be injected. The target process is then started, resulting in the execution of the inserted instructions. Once these instructions have been executed, the original starting instructions are restored back into the starting address. The process resumes execution from the starting address as if nothing had happened.